<template>
<div :class="[$style.container]" v-loading="renderedLoading">
  <div :class="[$style.header]">
    <div><el-button type="text" @click="onForward(-1)" :disabled="idx <= 0">上一个</el-button></div>
    <div>
      <el-button type="text" class="mr-3" @click="expand = !expand">
        <span v-if="expand">收起列表</span>
        <span v-else>展开列表</span>
      </el-button>
      <el-dropdown>
        <el-button type="text">
          <span>{{type.label}}</span>
          <span class="ml-1">{{idx + 1}} / {{len}}</span>
          <span class="ml-1"><i class="el-icon-arrow-down"></i></span>
        </el-button>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item :class="[typeSelectedCls(row)]" v-for="(row, i) in types" :key="i" @click.native="onSelectType(row)">
            <span class="mx-3">
              <span class="ml-2">{{row.label}}</span>
            </span>
          </el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      <el-button type="text" class="ml-3" @click="onForward(1)" :disabled="idx >= len - 1">下一个</el-button>
    </div>
  </div>
  <div :class="[$style.body]">
    <ul :class="[$style.list]" v-show="expand" v-if="renderedRows.length > 0">
      <li :class="[$style.item, rowSelectedCls(row)]" v-for="(row, i) in renderedRows" :key="i" @click="onSelect(row, i)">
        <div :class="[$style.icon]"><doc-icon :data="row"></doc-icon></div>
        <div :class="[$style.text]" :title="row.name">{{row.name}}</div>
      </li>
    </ul>
    <empty-data class="my-3" v-if="expand && renderedRows.length < 1">暂无文档</empty-data>
  </div>
</div>
</template>

<script lang="ts">

import { getDocById, getUserDocs } from '@/api/doc'
import { Vue, Component, Provide, Watch, Ref, Prop, Emit } from 'vue-property-decorator'
import { getSuffixesByType, getType } from '@/config/content-type'
import { getHistoryDoc } from '@/api/doc-history'
import { getDocByLink, queryDocsByLink } from '@/api/doc-share'
import { PageData, PageQueryParams } from '@/config/page'

const types = [
  { name: '', label: '全部' },
  { name: 'office', label: 'office文档' },
  { name: 'pdf', label: 'pdf' },
  { name: 'image', label: '图片' },
  { name: 'video', label: '视频' },
  { name: 'audio', label: '音频' },
  { name: 'text', label: '文本' }
]

const eq = (o1: any, o2: any) => o1 === o2 || (o1?.id === o2?.id)

@Component
export default class FileGallery extends Vue {
  @Prop(String) parentId!: string

  @Prop(String) id!: string

  @Prop(String) versionId!: string

  @Prop(String) linkId!: string

  @Prop(String) accessCode!: string

  @Prop() current!: any

  @Emit('update:current') updateCurrent (current: any) {}

  rows: any[] = []

  loading = false

  pageData: PageData<any> = null as any

  type: any = types[0]

  types = types

  expand = true

  doc: any = null

  get renderedRows () {
    const rows: any[] = this.pageData ? this.pageData.rows : this.rows
    return rows.filter(v => {
      if (!this.type?.name) return true
      const type = getType(v.name)
      return type === this.type?.name
    })
  }

  get len () {
    return this.pageData ? this.pageData.total : this.renderedRows.length
  }

  get idx () {
    return this.renderedRows.findIndex(v => eq(this.current, v))
  }

  get renderedLoading () {
    return this.pageData ? this.pageData.loading : this.loading
  }

  typeSelectedCls (row: any) {
    return row === this.type ? 'selected' : ''
  }

  rowSelectedCls (row: any) {
    return eq(row, this.current) ? this.$style.selected : ''
  }

  onSelectType (row: any) {
    this.type = row
    this.remoteLoadData()
  }

  onSelect (row: any, i: number) {
    if (this.pageData && i >= this.renderedRows.length - 1) {
      this.pageData.loadNext()
    }
    this.updateCurrent(row)
  }

  onForward (offset: number) {
    const n = Math.max(0, Math.min(this.idx + offset, this.len - 1))
    const item = this.renderedRows[n]
    if (item) this.onSelect(item, n)
  }

  loadData () {
    this.loading = true
    if (this.versionId) {
      getHistoryDoc(Number(this.versionId)).then(data => {
        this.rows = (data && [data]) || []
        this.updateCurrent(data || null)
      }).finally(() => {
        this.loading = false
      })
    } else if (this.parentId) {
      this.remoteLoadData()
    } else {
      const request = this.linkId ? getDocByLink(Number(this.linkId), Number(this.id)) : getDocById(Number(this.id))
      request.then(data => {
        this.rows = (data && [data]) || []
        this.updateCurrent(data || null)
      }).finally(() => {
        this.loading = false
      })
    }
  }

  remoteLoadData () {
    this.pageData = new PageData((params: PageQueryParams) => {
      const contentType = this.type?.name ? getSuffixesByType(this.type?.name).join(',') : undefined
      const request = this.linkId
        ? queryDocsByLink(Number(this.linkId), { page: params.page, size: params.size, docContentType: contentType, docType: 'file', accessCode: this.accessCode, docParentId: Number(this.parentId) })
        : getUserDocs({ page: params.page, size: params.size, type: 'file', contentType }, Number(this.parentId))
      return request.then((data) => {
        return data
      })
    }, { size: 30 })

    this.pageData.loadNext().then(() => {
      this.loadDoc().then(doc => {
        if (doc && (!this.type?.name || getType(doc.name) === this.type?.name)) {
          const current = this.pageData.rows.find(v => v.id === doc.id)
          if (current) {
            this.updateCurrent(current)
          } else {
            this.pageData.rows.splice(0, 0, doc)
            this.updateCurrent(doc)
          }
        } else {
          if (this.pageData?.rows[0]) this.updateCurrent(this.pageData.rows[0])
        }
      })
    })
  }

  loadDoc () {
    if (this.id) {
      return getDocById(Number(this.id)).then(data => {
        this.doc = data || null
        return this.doc
      })
    } else {
      return Promise.resolve(null)
    }
  }

  created () {
    this.loadData()
  }

  $style!: any
}
</script>

<style lang="scss" module>
@import "~@/styles/vars.scss";

$header-height: 36px;

.container {
}

.header {
  height: $header-height;
  padding: 0 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-top: 1px solid $border-split-color;
  box-shadow: 0 1px 4px rgba(0,21,41,.08);
}

.body {
  box-sizing: border-box;
  width: 100%;
  padding: 0 40px;
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  overflow: auto;
  display: flex;
  width: 0;
  min-width: 100%;
}

.item {
  flex: 0 0 auto;
  height: 112px;
  width: 100px;
  margin: 8px 4px;
  padding: 4px;
  box-sizing: border-box;
  border: 1px solid $border-color;
  border-radius: 2px;

  display: flex;
  flex-direction: column;
  justify-content: space-between;

  &:hover {
    cursor: pointer;
    border-color: $text-placeholder-color;
  }

  &.selected {
    border-color: $color-primary;
  }
}

.icon {
  font-size: 48px;
  text-align: center;
}

.text {
  margin-top: 8px;
  font-size: 12px;
  text-align: center;
  overflow : hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
</style>
